/**
 * 
 */
package com.douyu.ocean.recom.platform.api.component.bypass;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * @author leiruiqi
 *
 */
public abstract class BypassComponent {

	public static Map<String,BypassComponent> allBypassComponents = new HashMap<String,BypassComponent>();
	
	@PostConstruct
	public void initComponents(){
		allBypassComponents.put(this.getComponentKey(),this);
	}
	
	public abstract String getComponentKey();
	
	public static int getNum(String componentKey,String expression,Long uid){
		
		BypassComponent co = allBypassComponents.get(componentKey);
		
		if(co == null){
			throw new RuntimeException("compomentKey not exit");
		}
		
		return co.getByPassResultNum(expression, uid);
	}
	
	/**
	 * 
	 * 根据范围表达式和uid分析，计算出分流区间 
	 * 比如：只有3个候选项，那么只有可能返回0，1，2
	 * 
	 * 表达式里是自定义规则，由具体的组件类实现。
	 * 
	 * 类型为字符串，根据字符串解析规则，算出最终结果。
	 * 
	 * 
	 * @param expression
	 * @param uid
	 * @return
	 */
	public abstract int getByPassResultNum(String expression,Long uid);
	
	public abstract boolean checkExpression(String expression);
	
	public static <T> T getBypassResult(List<T> choiseList,String componentKey,String expression,Long uid){
		
		
		if(CollectionUtils.isEmpty(choiseList)){
			throw new RuntimeException();
		}
		if(choiseList.size()==1){
			return choiseList.get(0);
		}
		int num = getNum(componentKey,expression,uid);
		
		if(num >= choiseList.size()){
			return choiseList.get(0);
		}
		else{
			return choiseList.get(num);
		}
	}
	
	public static <T> T getBypassResult(List<T> choiseList,String componentExpression,Long uid){
		
		String[] expressionArr = StringUtils.split(componentExpression, ":");
		if(CollectionUtils.isEmpty(choiseList)){
			throw new RuntimeException();
		}
		if(choiseList.size()==1){
			return choiseList.get(0);
		}
		
		
		int num = getNum(expressionArr[0],expressionArr[1],uid);
		
		if(num >= choiseList.size()){
			return choiseList.get(0);
		}
		else{
			return choiseList.get(num);
		}
	}
	
}
